package com.bdqn.business.academic.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bdqn.base.BaseService;
import com.bdqn.business.academic.dao.*;
import com.bdqn.business.access.dao.UserRepository;
import com.bdqn.business.quality.dao.ClassesMapper;
import com.bdqn.business.quality.dao.StudentManagerMapper;
import com.bdqn.business.student.dao.AskResultMapper;
import com.bdqn.business.student.dao.UpperResultMapper;
import com.bdqn.entity.academic.*;
import com.bdqn.entity.access.User;
import com.bdqn.entity.quality.Classes;
import com.bdqn.entity.quality.Student;
import com.bdqn.entity.student.AskResult;
import com.bdqn.entity.student.UpperResult;
import com.bdqn.error.CommonException;
import com.bdqn.response.PageResult;
import com.bdqn.response.Result;
import com.bdqn.response.ResultCode;
import com.bdqn.utils.BeanMapUtils;
import com.bdqn.utils.DateUtils;
import com.bdqn.utils.IdWorker;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Transactional
@SuppressWarnings("all")
public class ExamService extends BaseService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private ClassesMapper classesMapper;

    @Autowired
    private ExamMapper examMapper;

    @Autowired
    private SingleMapper singleMapper;

    @Autowired
    private SelectionMapper selectionMapper;

    @Autowired
    private AskMapper askMapper;

    @Autowired
    private UpperMapper upperMapper;


    @Autowired
    private StudentManagerMapper studentManagerMapper;

    @Autowired
    private ScoreMapper scoreMapper;

    @Autowired
    private AskResultMapper askResultMapper;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UpperResultMapper upperResultMapper;


    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public Result getExamList(Map<String, Object> map) {
        Integer page = Integer.parseInt(map.get("page").toString());
        Integer size = Integer.parseInt(map.get("size").toString());
        IPage<Exam> iPage = new Page<>(page,size);
        QueryWrapper<Exam> queryWrapper = new QueryWrapper<>();
        if(map.get("classesId") != null) queryWrapper.eq("classes_id",map.get("classesId").toString());
        if(map.get("classesName") != null) queryWrapper.like("classes_name",map.get("classesName").toString());
        if(map.get("examName") != null) queryWrapper.like("exam_name",map.get("examName").toString());
        if(map.get("examType") != null) queryWrapper.eq("exam_type",map.get("examType").toString());
        if(map.get("examStatus") != null) queryWrapper.eq("exam_status",map.get("examStatus").toString());


        if(map.get("questionType") != null && map.get("questionType").toString().equals("1")){
            queryWrapper.ne("question_type_ids","4");
        }else if (map.get("questionType") != null && map.get("questionType").toString().equals("2")){
            queryWrapper.eq("question_type_ids","4");
        }
        queryWrapper.orderByDesc("create_time");
        IPage<Exam> result = examMapper.selectPage(iPage, queryWrapper);
        PageResult<Exam> pageResult = new PageResult<>(result.getTotal(),result.getRecords());
        return new Result(ResultCode.SUCCESS,pageResult);
    }

    public Result save(Map<String, Object> map) throws Exception {

        //试卷出题的时间  examTime
        Date examTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(map.get("examTime").toString());


        //拿到出题的时间干什么事？  新锐02班 日测   周测 月考

        //试卷类型
        String examType = map.get("examType").toString();  //1 是日测  2 是周测  3是月考
        //参考班级
        String classesId = map.get("classesId").toString();
        //试卷题型
        String questionTypeIds = map.get("questionTypeIds").toString(); //1是单选题 2 是多选题 3是问答题 4是上机题

        if("1".equals(examType)){ //如果等于日测

            //因为日测可以有两种题型试卷： 只有机试试卷 和 只有除了机试的试卷
            if(questionTypeIds.contains("4")){
                //如果日测中只有机试题存在时，需要判断当日日测是否已经出了日测题，如果已出，则驳回
                Exam target = examMapper.getExamByUpperExamTypeAndClassesIdAndExamTime(examType,classesId,examTime);
                if( target  != null ) return new Result(ResultCode.EXAM_DAY_IS_ALWAYS);

            }else{
                //如果日测中没有机试题存在时，需要判断当日日测是否已经出了日测题，如果已出，则驳回
                Exam targetExam = examMapper.getExamByExamTypeAndClassesIdAndExamTime(examType,classesId,examTime);
                if(targetExam != null) return new Result(ResultCode.EXAM_DAY_IS_ALWAYS);
            }

        }else if("2".equals(examType)){ //周测

            //获取当前日所在的周一和周日
            String timeInterval = DateUtils.getTimeInterval(examTime);
            String[] split = timeInterval.split(",");
            Date start = new SimpleDateFormat("yyyy-MM-dd").parse(split[0]);
            Date end = new SimpleDateFormat("yyyy-MM-dd").parse(split[1]);

            if(questionTypeIds.contains("4")){
                //如果周测中只有机试题存在时，需要判断当周周测是否已经出了周测题，如果已出，则驳回
                List<Exam> targetExam = examMapper.getWeekUpperExamByExamTypeAndClassesIdAndStartAndEnd(examType,classesId,start,end);
                if(targetExam != null && targetExam.size() == 1) return new Result(ResultCode.EXAM_WEEK_IS_ALWAYS);
            }else{
                //如果周测中没有机试题存在时，需要判断当周周测是否已经出了周测题，如果已出，则驳回
                List<Exam> targetExam = examMapper.getWeekExamByExamTypeAndClassesIdAndStartAndEnd(examType,classesId,start,end);
                if(targetExam != null && targetExam.size() == 1 ) return new Result(ResultCode.EXAM_WEEK_IS_ALWAYS);
            }
        }else if("3".equals(examType)){ //月考

            //获取当日所在月的第一天和最后一天
            Date start = DateUtils.getFirstDayDateOfMonth(examTime);
            Date end = DateUtils.getLastDayOfMonth(examTime);
            if(questionTypeIds.contains("4")){
                List<Exam> targetExam = examMapper.getWeekUpperExamByExamTypeAndClassesIdAndStartAndEnd(examType,classesId,start,end);
                if(targetExam != null && targetExam.size() == 1) return new Result(ResultCode.EXAM_MONTH_IS_ALWAYS);
            }else{
                List<Exam> targetExam = examMapper.getWeekExamByExamTypeAndClassesIdAndStartAndEnd(examType,classesId,start,end);
                if(targetExam != null && targetExam.size() == 1) return new Result(ResultCode.EXAM_MONTH_IS_ALWAYS);
            }
        }



        if(map.get("singleScore") != null) map.put("singleScore",Integer.parseInt(map.get("singleScore").toString()));
        if(map.get("selectionScore") != null) map.put("selectionScore",Integer.parseInt(map.get("selectionScore").toString()));
        if(map.get("askScore") != null) map.put("askScore",Integer.parseInt(map.get("askScore").toString()));
        if(map.get("upperScore") != null) map.put("upperScore",Integer.parseInt(map.get("upperScore").toString()));
        map.put("examTime",examTime);


        Exam exam = BeanMapUtils.mapToBean(map, Exam.class);


        //出题方式 1手动出题，2自动出题
        String examPattern = exam.getExamPattern();


        if("1".equals(examPattern)){ //手动出题，暂未实现

        }else if("2".equals(examPattern)){

            String chapterIds = exam.getChapterIds();

            List<Single> singleList = new ArrayList<>();
            List<Selection> selectionList = new ArrayList<>();
            List<Ask> askList = new ArrayList<>();


            for (String chapterId : chapterIds.split(",")) {

                //查询提交章节组的所有单选题集合
                QueryWrapper<Single> singleQueryWrapper = new QueryWrapper<>();
                singleQueryWrapper.eq("chapter_id",chapterId);
                List<Single> querySingleList = singleMapper.selectList(singleQueryWrapper);

                if(querySingleList != null && querySingleList.size() > 0){
                    for (Single single : querySingleList) {
                        singleList.add(single);
                    }
                }

                QueryWrapper<Selection> selectionQueryWrapper = new QueryWrapper<>();
                selectionQueryWrapper.eq("chapter_id",chapterId);
                List<Selection> querySelectionList = selectionMapper.selectList(selectionQueryWrapper);

                if(querySelectionList != null && querySelectionList.size() > 0){
                    for (Selection selection : querySelectionList) {
                        selectionList.add(selection);
                    }
                }

                QueryWrapper<Ask> askQueryWrapper = new QueryWrapper<>();
                askQueryWrapper.eq("chapter_id",chapterId);
                List<Ask> queryAskList = askMapper.selectList(askQueryWrapper);
                if(queryAskList != null && queryAskList.size() > 0){
                    for (Ask ask : queryAskList) {
                        askList.add(ask);
                    }
                }
            }

            //如果题型中包含单选题
            if(questionTypeIds.contains("1")){
                Integer singleCount = exam.getSingleCount();
                if(singleList.size() < singleCount){
                    return new Result(ResultCode.QUESTION_SIZE_OUTPUT);
                }

                Collections.shuffle(singleList,new Random(3)); //打乱3次
                List<Single> singles = singleList.subList(0, singleCount);

                List<String> singleIds = new ArrayList<>();

                for (Single single : singles) {
                    singleIds.add(single.getId());
                }

                String singleJoin = StringUtils.join(singleIds, ",");

                exam.setSingleJoins(singleJoin);
            }


            //如果题型中包含多选题
            if(questionTypeIds.contains("2")){

                Integer selectionCount = exam.getSelectionCount();

                if(selectionList.size() < selectionCount){
                    return new Result(ResultCode.QUESTION_SIZE_OUTPUT);
                }

                Collections.shuffle(selectionList,new Random(3));

                List<Selection> selections = selectionList.subList(0, selectionCount);

                List<String> selectionIds = new ArrayList<>();

                for (Selection selection : selections) {
                    selectionIds.add(selection.getId());
                }

                String selectionJoin = StringUtils.join(selectionIds, ",");

                exam.setSelectionJoins(selectionJoin);

            }

            //如果题型中包含问答题
            if(questionTypeIds.contains("3")){

                Integer askCount = exam.getAskCount();

                if(askList.size() < askCount){
                    return new Result(ResultCode.QUESTION_SIZE_OUTPUT);
                }


                Collections.shuffle(askList,new Random(3));

                List<Ask> asks = askList.subList(0, askCount);

                List<String> askIds = new ArrayList<>();

                for (Ask ask : asks) {
                    askIds.add(ask.getId());
                }

                String askJoin = StringUtils.join(askIds, ",");

                exam.setAskJoins(askJoin);


            }


            //如果题型中包含上机题 已经映射到map中了
        }


        Classes classes = classesMapper.selectById(exam.getClassesId());
        exam.setClassesName(classes.getClassesName());
        exam.setId(idWorker.nextId() + "");
        exam.setPersonNumber(classes.getPersonNumber());
        exam.setExamStatus("1"); //未开始

        exam.setCreateTime(new Date());
        exam.setModifyId(currentUser().getId());
        exam.setModifyUser(currentUser().getNickName());
        exam.setModifyTime(new Date());

        //TODO:新增的一条
        exam.setAskOver("1");//没有完成全部已考学生的问答题的批阅

        examMapper.insert(exam);

        return Result.SUCCESS();

    }



    public Result findById(String id) {
        Exam exam = examMapper.selectById(id);
        if("1".equals(exam.getExamStatus())){
            return Result.SUCCESS();
        }else{
            return Result.FAIL();
        }
    }



    public Result start(Exam exam) {

        //教师点击开始考试按钮  1 -> 2
        exam.setExamStatus("2");//状态为2 进行中
        exam.setModifyId(currentUser().getId());
        exam.setModifyUser(currentUser().getNickName());
        exam.setModifyTime(new Date());
        examMapper.updateById(exam);


        //把该试卷的所有试题生成一个试卷,存入到redis中
        //在exam中存储的是什么东西？  是不是存储的是单选题的id组  多选题的id组 问答题的id组  上机题的id
        Map<String, Object> map = new HashMap<>();;
        List<Single> singles = new ArrayList<>();
        List<Selection> selections = new ArrayList<>();
        List<Ask> asks = new ArrayList<>();
        List<Upper> uppers = new ArrayList<>();


        //如果试卷中存在单选题，则拿出试卷中的单选题集合
        String questionTypeIds = exam.getQuestionTypeIds(); //1是单选题  2 是多选题 3是问答题 4是上机题
        if(questionTypeIds.contains("1")){
            //获取当前试卷的单选题id组
            String singleJoins = exam.getSingleJoins();
            //以，号切割单选题id组
            for (String singleId : singleJoins.split(",")) {
                Single single = singleMapper.findByIdNoAnswer(singleId);
                singles.add(single);
            }
        }

        //如果试卷中存在多选题，则拿出试卷中的多选题集合
        if(questionTypeIds.contains("2")){
            String selectionJoins = exam.getSelectionJoins();
            for (String selectionId : selectionJoins.split(",")) {
                Selection selection = selectionMapper.findByIdNoAnswer(selectionId);
                selections.add(selection);
            }
        }

        //如果试卷中存在问答题，则拿出试卷中的问答题集合
        if(questionTypeIds.contains("3")){
            String askJoins = exam.getAskJoins();
            for (String askId : askJoins.split(",")) {
                Ask ask = askMapper.findByIdNoAnswer(askId);
                asks.add(ask);
            }
        }


        //如果试卷中存在上机题，则拿出试卷中的上机题集合
        if(questionTypeIds.contains("4")){
            String upperJoins = exam.getUpperJoins();
            Upper upper = upperMapper.selectById(upperJoins);
            uppers.add(upper);
        }


        map.put("singleList",singles);
        map.put("selectionList",selections);
        map.put("askList",asks);
        map.put("upperList",uppers);


        //现在我们已经准备完数据了， 我们需要把当前的这个map数据存储到redis中，让学生从reids中拿取这个数据然后展示到页面上
        redisTemplate.opsForValue().set("exam"+exam.getId(),JSON.toJSONString(map));


        //初始化所有学生当前试卷的score成绩
        String classesId = exam.getClassesId();
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("classes_id",classesId);
        List<Student> students = studentManagerMapper.selectList(queryWrapper);

        if(students != null && students.size() > 0){
            //遍历学生集合
            for (Student student : students) {

                Score score = Score.builder()
                        .executeTime(new Date())
                        .studentId(student.getId())
                        .score(0)
                        .examId(exam.getId())
                        .askScore(0)
                        .upperScore(0)
                        .singleScore(0)
                        .selectionScore(0)
                        .singleErr(0)
                        .singleSucc(0)
                        .selectionErr(0)
                        .selectionSucc(0)
                        .singleSuccIds("")
                        .singleErrIds("")
                        .selectionSuccIds("")
                        .selectionErrIds("")
                        .status("0") //0初始化 未交卷1 已交卷2
                        .build();
                scoreMapper.insert(score);
            }
        }

        //如果有问答题 初始化学生问答题结果  st_ask_result
        if(questionTypeIds.contains("3")){
            //试卷中的问答题的id组
            String askJoins = exam.getAskJoins();

            for (Student student : students) {
                for (String askId : askJoins.split(",")) {
                    AskResult askResult = AskResult.builder()
                            .askId(askId)
                            .examId(exam.getId())
                            .studentId(student.getId())
                            .score(0)
                            .markingStatus("1")
                            .askAnswer("暂无")
                            .teacherComment("暂无")
                            .build();
                    askResultMapper.insert(askResult);
                }
            }
        }

        //如果有上机题 初始化学生上机题结果 st_upper_result
        if(questionTypeIds.contains("4")){
            String upperJoins = exam.getUpperJoins();
            for (Student student : students) {
                for (String upperd : upperJoins.split(",")) {
                    UpperResult upperResult = UpperResult.builder()
                            .upperId(upperd)
                            .examId(exam.getId())
                            .studentId(student.getId())
                            .score(0)
                            .markingStatus("1")
                            .url(null)
                            .build();
                    upperResultMapper.insert(upperResult);
                }
            }
        }

        return Result.SUCCESS();



    }

    public Result getStudentScoreListByExam(Exam exam) {

        //通过试卷id查询学生成绩表
        QueryWrapper<Score> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("exam_id",exam.getId());
        List<Score> scores = scoreMapper.selectList(queryWrapper);
        if(scores != null && scores.size() > 0){
            for (Score score : scores) {
                User user = userRepository.findById(score.getStudentId()).get();
                score.setStudentName(user.getNickName());
            }
        }
        return new Result(ResultCode.SUCCESS,scores);
    }

    public Result stopExam(Exam exam) {
        String questionTypeIds = exam.getQuestionTypeIds();
        String examType = exam.getExamType();

        //记录没有考试的人数
        int count = 0;

        //查询考试的学生集合
        String classesId = exam.getClassesId();
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("classes_id",classesId);
        queryWrapper.eq("study_type","1");//在读状态
        List<Student> students = studentManagerMapper.selectList(queryWrapper);


        for (Student student : students) {
            QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
            scoreQueryWrapper.eq("student_id",student.getId());
            scoreQueryWrapper.eq("exam_id",exam.getId());
            Score score = scoreMapper.selectOne(scoreQueryWrapper);

            if("1".equals(score.getStatus())){
                score.setStatus("2");
                scoreMapper.updateById(score);
            }else if("0".equals(score.getStatus())){
                count ++;
            }
        }

        if(examType.equals("1") && !questionTypeIds.contains("3") && !questionTypeIds.contains("4")){ //日测 + 不包含问答题 + 不包含上机题
            exam.setExamStatus("6");//试卷修改为结束状态,日测直接结束, 不用补考
        }else if(examType.equals("1") && (questionTypeIds.contains("3")  || questionTypeIds.contains("4"))){ //日测 + 可能包含问答题 + 可能包含上机题
            exam.setExamStatus("3"); //有批阅无补考（只针对日测）
        }else if(!examType.equals("1") && count > 0 && (questionTypeIds.contains("3") || questionTypeIds.contains("4"))){//周测或月考 + 有未参考学生 + 有可能包含问答题 + 有可能包含上机题
            exam.setExamStatus("4"); //有批阅且补考
        }else if(!examType.equals("1") && count > 0 && (!questionTypeIds.contains("3") && !questionTypeIds.contains("4"))){ //周测或月考 + 有未参考学生 + 不包含问答题 + 不包含上机题
            exam.setExamStatus("5"); //无批阅但补考
        }else if(!examType.equals("1") && count == 0 && (questionTypeIds.contains("3") || questionTypeIds.contains("4"))){ //周测或月考 + 没有参考学生 + 有可能包含问答题 + 有可能包含上机题
            exam.setExamStatus("4"); //有批阅且补考
        }else if(!examType.equals("1") && count == 0 && (!questionTypeIds.contains("3") && !questionTypeIds.contains("4"))){ //周测或月考 + 没有参考学生 + 不包含问答题 + 不包含上机题
            exam.setExamStatus("5"); //无批阅但补考
        }

        examMapper.updateById(exam);

        return Result.SUCCESS();
    }


    public Result getStudentAskResultList(Exam exam) {
        String classesId = exam.getClassesId();

        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("classes_id",classesId);

        List<Student> students = studentManagerMapper.selectList(queryWrapper);

        Map<String,Object> returnMap = new HashMap<>();

        List<Map<String,Object>> returnList = new ArrayList<>();

        if(students != null && students.size() > 0 ){
            for (Student student : students) {
                Map<String,Object> map = new HashMap<>();
                QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
                scoreQueryWrapper.eq("student_id",student.getId());
                scoreQueryWrapper.eq("exam_id",exam.getId());
                scoreQueryWrapper.eq("status","2");
                Score score = scoreMapper.selectOne(scoreQueryWrapper);
                if(score != null){
                    //装载问答题未评分学生多个简答题答案(单人)
                    List<AskResult> list = new ArrayList<>();
                    for (String askId : exam.getAskJoins().split(",")) {
                        QueryWrapper<AskResult> askResultQueryWrapper = new QueryWrapper<>();
                        askResultQueryWrapper.eq("ask_id",askId);
                        askResultQueryWrapper.eq("student_id",student.getId());
                        askResultQueryWrapper.eq("exam_id",exam.getId());
                        askResultQueryWrapper.eq("marking_status","1"); //剔除已评分的学生
                        AskResult askResult = askResultMapper.selectOne(askResultQueryWrapper);
                        if(askResult != null){
                            list.add(askResult);
                        }

                    }


                    if(list.size() > 0){
                        User user = userRepository.findById(student.getId()).get();
                        map.put("user",user);
                        map.put("list",list);
                        returnList.add(map);
                    }
                }
            }
        }

        List<Ask> asks = new ArrayList<>();
        for (String askId : exam.getAskJoins().split(",")) {
            Ask ask = askMapper.selectById(askId);
            asks.add(ask);
        }

        returnMap.put("asks",asks);
        returnMap.put("list",returnList);

        return new Result(ResultCode.SUCCESS,returnMap);
    }

    public Result updateStudentAskScore(List<AskResult> askResults) throws CommonException {
        //获得试卷id，学生id
        AskResult askResult = askResults.get(0);
        String examId = askResult.getExamId();
        String studentId = askResult.getStudentId();

        QueryWrapper<Score> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("exam_id",examId);
        queryWrapper.eq("student_id",studentId);
        Score score = scoreMapper.selectOne(queryWrapper);
        //获得这个学生的问答题总分数
        Integer askScore = score.getAskScore();
        //获得这个学生的总分数
        Integer totalScore = score.getScore();

        Exam exam = examMapper.selectById(examId);
        Integer askScore1 = exam.getAskScore();

        for (AskResult result : askResults) {

            if(askScore1 >= result.getScore()){
                askScore += result.getScore();
                result.setMarkingStatus("2");
                askResultMapper.updateById(result);
            }else{
                throw new CommonException(ResultCode.SCORE_MORE_BIG);
            }
        }
        totalScore += askScore;
        score.setScore(totalScore);
        score.setAskScore(askScore);
        scoreMapper.updateById(score);



        //当前试卷的问答题是否全部批阅完毕
        int sum = 0; //记录未批阅问答题的数量
        //查询班级所有的学生
        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.eq("classes_id",exam.getClassesId());
        List<Student> students = studentManagerMapper.selectList(studentQueryWrapper);

        if(exam.getExamType().equals("1")){ //日测，不需要补考
            for (Student student : students) {
                //获得每个学生的成绩数据
                QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
                scoreQueryWrapper.eq("student_id",student.getId());
                scoreQueryWrapper.eq("exam_id",examId);
                Score dayScore = scoreMapper.selectOne(scoreQueryWrapper);
                //如果已经提交，则累加问答题没有判分的数量
                if(dayScore.getStatus().equals("2")){
                    QueryWrapper<AskResult> askResultQueryWrapper = new QueryWrapper<>();
                    askResultQueryWrapper.eq("exam_id",examId);
                    askResultQueryWrapper.eq("marking_status","1"); //问答题未批阅
                    askResultQueryWrapper.eq("student_id",student.getId());
                    Integer count = askResultMapper.selectCount(askResultQueryWrapper);
                    sum += count;
                }
            }
            //如果没有判分数量等于0，则说明问答题已经全部批阅完毕
            if(sum == 0){

                //设置问答题已批阅完成
                exam.setAskOver("2");

                //判断当前试卷是否包含上机题，如果不包含上机题，则直接结束试卷
                if(exam.getQuestionTypeIds().contains("3") && !exam.getQuestionTypeIds().contains("4")){

                    exam.setExamStatus("6");
                }
                examMapper.updateById(exam);
                return new Result(ResultCode.ANNOTATE_OK);
            }else{
                return new Result(ResultCode.ANNOTATE_NO);
            }
        }else {//周测或月考，需要补考，所以要查询没有交卷的数量

            //查询没有交卷的数量
            QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
            scoreQueryWrapper.eq("exam_id",examId);
            scoreQueryWrapper.ne("status","2"); //不等于2
            Integer count = scoreMapper.selectCount(scoreQueryWrapper);

            //如果没有交卷的数量不等于0，说明还有没交卷的，需要补考，不能结束试卷，还需要等补考人员提交试卷后，给问答题判分
            if(count != 0){
                return new Result(ResultCode.ANNOTATE_NO);
            }else if(count == 0){ //如果没有交卷的数量等于0，说明全部交卷，那么需要查看还有多少问答题没有批阅

                for (Student student : students) {
                    QueryWrapper<AskResult> askResultQueryWrapper = new QueryWrapper<>();
                    askResultQueryWrapper.eq("exam_id",examId);
                    askResultQueryWrapper.eq("marking_status","1"); //问答题未批阅
                    askResultQueryWrapper.eq("student_id",student.getId());
                    Integer count1 = askResultMapper.selectCount(askResultQueryWrapper);
                    sum += count1;
                }

                if(sum == 0){
                    exam.setAskOver("2");

                    //判断当前试卷是否包含上机题，如果不包含上机题，则直接结束试卷
                    /*if(exam.getQuestionTypeIds().contains("3") && !exam.getQuestionTypeIds().contains("4")){
                        exam.setExamStatus("6");
                    }*/

                    examMapper.updateById(exam);

                    return new Result(ResultCode.ANNOTATE_OK);
                }else{
                    return new Result(ResultCode.ANNOTATE_NO);
                }
            }else{
                throw new CommonException(ResultCode.FAIL);
            }
        }
    }

    public Result getStudentUpperResultList(Exam exam) {
        String classesId = exam.getClassesId();
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("classes_id",classesId);
        List<Student> students = studentManagerMapper.selectList(queryWrapper);

        Map<String,Object> returnMap = new HashMap<>();

        List<UpperResult> returnList = new ArrayList<>();

        if(students != null && students.size() > 0 ){
            for (Student student : students) {
                //Map<String,Object> map = new HashMap<>();
                QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
                scoreQueryWrapper.eq("student_id",student.getId());
                scoreQueryWrapper.eq("exam_id",exam.getId());
                scoreQueryWrapper.eq("status","2");
                Score score = scoreMapper.selectOne(scoreQueryWrapper);
                if(score != null){
                    QueryWrapper<UpperResult> upperResultQueryWrapper = new QueryWrapper<>();
                    upperResultQueryWrapper.eq("student_id",student.getId());
                    upperResultQueryWrapper.eq("exam_id",exam.getId());
                    upperResultQueryWrapper.eq("marking_status","1"); //剔除已评分的学生
                    UpperResult upperResult = upperResultMapper.selectOne(upperResultQueryWrapper);

                    if(upperResult != null){
                        User user = userRepository.findById(student.getId()).get();
                        /*map.put("user",user);
                        map.put("upperResult",upperResult);*/
                        upperResult.setNickName(user.getNickName());
                        returnList.add(upperResult);
                    }
                }
            }
        }

        List<Upper> uppers = new ArrayList<>();
        for (String upperId : exam.getUpperJoins().split(",")) {
            Upper upper = upperMapper.selectById(upperId);
            uppers.add(upper);
        }

        returnMap.put("uppers",uppers);
        returnMap.put("list",returnList);

        return new Result(ResultCode.SUCCESS,returnMap);
    }

    public Result updateStudentUpperScore(List<UpperResult> upperResults) throws CommonException {
        //获得试卷id，学生id
        UpperResult upperResult = upperResults.get(0);
        String examId = upperResult.getExamId();
        String studentId = upperResult.getStudentId();

        QueryWrapper<Score> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("exam_id",examId);
        queryWrapper.eq("student_id",studentId);
        Score score = scoreMapper.selectOne(queryWrapper);
        //获得这个学生的上机题总分数
        Integer upperScore = score.getUpperScore();

        //获得这个学生的总分数
        Integer totalScore = score.getScore();

        Exam exam = examMapper.selectById(examId);
        Integer upperScore1 = exam.getUpperScore();

        for (UpperResult result : upperResults) {
            if(upperScore1 >= result.getScore()){
                upperScore += result.getScore();
                result.setMarkingStatus("2");
                upperResultMapper.updateById(result);
            }else{
                throw new CommonException(ResultCode.SCORE_MORE_BIG);
            }
        }


        totalScore += upperScore;
        score.setScore(totalScore);
        score.setUpperScore(upperScore);
        scoreMapper.updateById(score);



        //当前试卷的问答题是否全部批阅完毕
        int sum = 0; //记录未批阅上机题的数量
        //查询班级所有的学生
        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.eq("classes_id",exam.getClassesId());
        List<Student> students = studentManagerMapper.selectList(studentQueryWrapper);

        if(exam.getExamType().equals("1")){ //日测，不需要补考
            for (Student student : students) {
                //获得每个学生的成绩数据
                QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
                scoreQueryWrapper.eq("student_id",student.getId());
                scoreQueryWrapper.eq("exam_id",examId);
                Score dayScore = scoreMapper.selectOne(scoreQueryWrapper);
                //如果已经提交，则累加上机题没有判分的数量
                if(dayScore.getStatus().equals("2")){
                    QueryWrapper<UpperResult> upperResultQueryWrapper = new QueryWrapper<>();
                    upperResultQueryWrapper.eq("exam_id",examId);
                    upperResultQueryWrapper.eq("marking_status","1"); //上机题未批阅
                    upperResultQueryWrapper.eq("student_id",student.getId());
                    Integer count = upperResultMapper.selectCount(upperResultQueryWrapper);
                    sum += count;
                }
            }
            //如果没有判分数量等于0，则说明上机题已经全部批阅完毕
            if(sum == 0){

                //设置上机题已批阅完成
                exam.setUpperOver("2");
                //判断当前试卷是否包含上机题，如果不包含上机题，则直接结束试卷
                if(exam.getQuestionTypeIds().contains("3") && !exam.getQuestionTypeIds().contains("4")){

                    exam.setExamStatus("6");
                }
                examMapper.updateById(exam);
                return new Result(ResultCode.ANNOTATE_OK);
            }else{
                return new Result(ResultCode.ANNOTATE_NO);
            }
        }else {//周测或月考，需要补考，所以要查询没有交卷的数量

            //查询没有交卷的数量
            QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
            scoreQueryWrapper.eq("exam_id",examId);
            scoreQueryWrapper.ne("status","2"); //不等于2
            Integer count = scoreMapper.selectCount(scoreQueryWrapper);

            //如果没有交卷的数量不等于0，说明还有没交卷的，需要补考，不能结束试卷，还需要等补考人员提交试卷后，给问答题判分
            if(count != 0){
                return new Result(ResultCode.ANNOTATE_NO);
            }else if(count == 0){ //如果没有交卷的数量等于0，说明全部交卷，那么需要查看还有多少问答题没有批阅

                for (Student student : students) {
                    QueryWrapper<AskResult> askResultQueryWrapper = new QueryWrapper<>();
                    askResultQueryWrapper.eq("exam_id",examId);
                    askResultQueryWrapper.eq("marking_status","1"); //问答题未批阅
                    askResultQueryWrapper.eq("student_id",student.getId());
                    Integer count1 = askResultMapper.selectCount(askResultQueryWrapper);
                    sum += count1;
                }

                if(sum == 0){
                    exam.setAskOver("2");

                    //判断当前试卷是否包含上机题，如果不包含上机题，则直接结束试卷
                    /*if(exam.getQuestionTypeIds().contains("4") && !exam.getQuestionTypeIds().contains("3")){
                        exam.setExamStatus("6");
                    }*/

                    examMapper.updateById(exam);

                    return new Result(ResultCode.ANNOTATE_OK);
                }else{
                    return new Result(ResultCode.ANNOTATE_NO);
                }
            }else{
                throw new CommonException(ResultCode.FAIL);
            }
        }
    }

    public Result overExam(Exam exam) {
        String examType = exam.getExamType();
        if(examType.equals("1")){//日测
            //直接结束考试
            exam.setExamStatus("6");
            exam.setUpperOver("2");
            exam.setAskOver("2");
            examMapper.updateById(exam);
            return Result.SUCCESS();
        }else{
            //查看是否有需要补考的学生,如果有，则不允许结束考试
            //找到这个试卷的这个班级中所有的学生
            String classesId = exam.getClassesId();
            QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("classes_id",classesId);
            List<Student> students = studentManagerMapper.selectList(queryWrapper);

            int count = 0;//未参考人员数量
            int askCount = 0; //问答题未评分人员数量
            int upperCount = 0;//上机题未评分人员数量

            List<User> users = new ArrayList<>();

            if(students != null && students.size() > 0){
                for (Student student : students) {
                    QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
                    scoreQueryWrapper.eq("student_id",student.getId());
                    scoreQueryWrapper.eq("exam_id",exam.getId());
                    Score score = scoreMapper.selectOne(scoreQueryWrapper);
                    if(!score.getStatus().equals("2")){
                        count++;
                        User user = userRepository.findById(student.getId()).get();
                        users.add(user);
                    }

                    if(exam.getQuestionTypeIds().contains("3")){ //包含问答题
                        QueryWrapper<AskResult> askResultQueryWrapper = new QueryWrapper<>();
                        askResultQueryWrapper.eq("student_id",student.getId());
                        askResultQueryWrapper.eq("exam_id",exam.getId());
                        List<AskResult> askResults = askResultMapper.selectList(askResultQueryWrapper);
                        if(askResults != null && askResults.size() > 0){
                            for (AskResult askResult : askResults) {
                                if(askResult.getMarkingStatus().equals("1")){
                                    askCount ++;
                                }
                            }
                        }
                    }

                    if(exam.getQuestionTypeIds().contains("4")){
                        QueryWrapper<UpperResult> upperResultQueryWrapper = new QueryWrapper<>();
                        upperResultQueryWrapper.eq("student_id",student.getId());
                        upperResultQueryWrapper.eq("exam_id",exam.getId());
                        List<UpperResult> upperResults = upperResultMapper.selectList(upperResultQueryWrapper);
                        if(upperResults != null && upperResults.size() > 0){
                            for (UpperResult upperResult : upperResults) {
                                if(upperResult.getMarkingStatus().equals("1")){
                                    upperCount ++;
                                }
                            }
                        }
                    }

                }
            }

            if(count == 0 && askCount == 0 && upperCount == 0){ //只有在全部补考 + 批阅全部的问答题 + 批阅全部的上机题之后才可以结束
                //直接结束考试
                exam.setExamStatus("6");
                exam.setUpperOver("2");
                exam.setAskOver("2");
                examMapper.updateById(exam);
                return Result.SUCCESS();
            }else{

                List<Student> scoreIsZeroStudentList = new ArrayList<>(); //未参考人员
                List<Student> askResultIsOneStudentList = new ArrayList<>();//问答题未评分人员
                List<Student> upperResultIsOneStudentList = new ArrayList<>(); //上机题未评分的人员

                if(students != null && students.size() > 0){

                    for (Student student : students) {
                        User user = userRepository.findById(student.getId()).get();
                        student.setNickName(user.getNickName());

                        QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
                        scoreQueryWrapper.eq("exam_id",exam.getId());
                        scoreQueryWrapper.eq("student_id",student.getId());
                        Score score = scoreMapper.selectOne(scoreQueryWrapper);
                        if(score != null && score.getStatus().equals("0")){//没考试,就得补考
                            scoreIsZeroStudentList.add(student);
                        }

                        String questionTypeIds = exam.getQuestionTypeIds();

                        if(questionTypeIds.contains("3") && !score.getStatus().equals("0")){//有问答题并且学生已经答卷
                            QueryWrapper<AskResult> askResultQueryWrapper = new QueryWrapper<>();
                            askResultQueryWrapper.eq("exam_id",exam.getId());
                            askResultQueryWrapper.eq("student_id",student.getId());
                            askResultQueryWrapper.eq("marking_status","1");
                            List<AskResult> askResults = askResultMapper.selectList(askResultQueryWrapper);
                            if(askResults != null && askResults.size() > 0){
                                askResultIsOneStudentList.add(student);
                            }
                        }

                        if(questionTypeIds.contains("4") && !score.getStatus().equals("0")){ //有上机题并且学生已经答卷
                            QueryWrapper<UpperResult> upperResultQueryWrapper = new QueryWrapper<>();
                            upperResultQueryWrapper.eq("student_id",student.getId());
                            upperResultQueryWrapper.eq("exam_id",exam.getId());
                            upperResultQueryWrapper.eq("marking_status","1");
                            UpperResult upperResult = upperResultMapper.selectOne(upperResultQueryWrapper);
                            if(upperResult != null){
                                upperResultIsOneStudentList.add(student);
                            }
                        }
                    }
                }

                Map<String,Object> map = new HashMap<>();
                map.put("scoreIsZeroStudentList",scoreIsZeroStudentList);
                map.put("askResultIsOneStudentList",askResultIsOneStudentList);
                map.put("upperResultIsOneStudentList",upperResultIsOneStudentList);

                return new Result(ResultCode.EXAM_IS_MAKEUP_EXAMINATION_PERSON,map);
            }
        }
    }

    public Result handleNotPerson(Exam exam) {

        String classesId = exam.getClassesId();

        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("classes_id",classesId);
        queryWrapper.eq("study_type","1");//在读状态
        List<Student> students = studentManagerMapper.selectList(queryWrapper);


        List<Student> scoreIsZeroStudentList = new ArrayList<>(); //未参考人员
        List<Student> askResultIsOneStudentList = new ArrayList<>();//问答题未评分人员
        List<Student> upperResultIsOneStudentList = new ArrayList<>(); //上机题未评分的人员

        if(students != null && students.size() > 0){

            for (Student student : students) {
                User user = userRepository.findById(student.getId()).get();
                student.setNickName(user.getNickName());

                QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
                scoreQueryWrapper.eq("exam_id",exam.getId());
                scoreQueryWrapper.eq("student_id",student.getId());
                Score score = scoreMapper.selectOne(scoreQueryWrapper);
                if(score != null && score.getStatus().equals("0")){//没考试,就得补考
                    scoreIsZeroStudentList.add(student);
                }

                String questionTypeIds = exam.getQuestionTypeIds();

                if(questionTypeIds.contains("3") && !score.getStatus().equals("0")){//有问答题并且学生已经答卷
                    QueryWrapper<AskResult> askResultQueryWrapper = new QueryWrapper<>();
                    askResultQueryWrapper.eq("exam_id",exam.getId());
                    askResultQueryWrapper.eq("student_id",student.getId());
                    askResultQueryWrapper.eq("marking_status","1");
                    List<AskResult> askResults = askResultMapper.selectList(askResultQueryWrapper);
                    if(askResults != null && askResults.size() > 0){
                        askResultIsOneStudentList.add(student);
                    }
                }

                if(questionTypeIds.contains("4") && !score.getStatus().equals("0")){ //有上机题并且学生已经答卷
                    QueryWrapper<UpperResult> upperResultQueryWrapper = new QueryWrapper<>();
                    upperResultQueryWrapper.eq("student_id",student.getId());
                    upperResultQueryWrapper.eq("exam_id",exam.getId());
                    upperResultQueryWrapper.eq("marking_status","1");
                    UpperResult upperResult = upperResultMapper.selectOne(upperResultQueryWrapper);
                    if(upperResult != null){
                        upperResultIsOneStudentList.add(student);
                    }
                }
            }
        }

        Map<String,Object> map = new HashMap<>();
        map.put("scoreIsZeroStudentList",scoreIsZeroStudentList);
        map.put("askResultIsOneStudentList",askResultIsOneStudentList);
        map.put("upperResultIsOneStudentList",upperResultIsOneStudentList);

        return new Result(ResultCode.SUCCESS,map);

    }

    public Result notConsult(String examId, String studentId) {
        Exam exam = examMapper.selectById(examId);
        String questionTypeIds = exam.getQuestionTypeIds();
        //操作学生的score表
        QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
        scoreQueryWrapper.eq("exam_id",examId);
        scoreQueryWrapper.eq("student_id",studentId);
        Score score = scoreMapper.selectOne(scoreQueryWrapper);
        score.setStatus("2");
        score.setModifyId(currentUser().getId());
        score.setModifyTime(new Date());
        score.setModifyUser(currentUser().getNickName());
        scoreMapper.updateById(score);

        //操作学生的ask_result表
        if(questionTypeIds.contains("3")){

            String askJoins = exam.getAskJoins();

            for (String askId : askJoins.split(",")) {
                QueryWrapper<AskResult> askResultQueryWrapper = new QueryWrapper<>();
                askResultQueryWrapper.eq("student_id",studentId);
                askResultQueryWrapper.eq("exam_id",examId);
                askResultQueryWrapper.eq("ask_id",askId);
                AskResult askResult = askResultMapper.selectOne(askResultQueryWrapper);
                askResult.setMarkingStatus("2");
                askResult.setScore(0);
                askResultMapper.updateById(askResult);
            }
        }


        //操作学生的upper_result表
        if(questionTypeIds.contains("4")){

            QueryWrapper<UpperResult> upperResultQueryWrapper = new QueryWrapper<>();
            upperResultQueryWrapper.eq("student_id",studentId);
            upperResultQueryWrapper.eq("exam_id",examId);
            UpperResult upperResult = upperResultMapper.selectOne(upperResultQueryWrapper);
            if(upperResult != null){
                upperResult.setMarkingStatus("2");
                upperResult.setScore(0);
                upperResultMapper.updateById(upperResult);
            }else{
                UpperResult upper = new UpperResult();
                upper.setScore(0);
                upper.setMarkingStatus("2");
                upper.setExamId(examId);
                upper.setUrl(null);
                upper.setStudentId(studentId);
                upperResultMapper.insert(upper);
            }
        }

        return Result.SUCCESS();

    }

    public Result analysisExam(Exam exam) {
        List<ScoreVo> vo = examMapper.getStudentInfoByExamId(exam.getId());
        return new Result(ResultCode.SUCCESS,vo);
    }

    public Result explainExam(Exam exam) {

        Map<String,Object> map = new HashMap<>();

        List<Single> singles = new ArrayList<>();
        List<Selection> selections = new ArrayList<>();
        List<Ask> asks = new ArrayList<>();
        List<Upper> uppers = new ArrayList<>();

        String questionTypeIds = exam.getQuestionTypeIds();

        if(questionTypeIds.contains("1")){
            String singleJoins = exam.getSingleJoins();
            for (String singleId : singleJoins.split(",")) {
                Single single = singleMapper.selectById(singleId);
                singles.add(single);
            }
        }

        if(questionTypeIds.contains("2")){
            String selectionJoins = exam.getSelectionJoins();
            for (String selectionId : selectionJoins.split(",")) {
                Selection selection = selectionMapper.selectById(selectionId);
                selections.add(selection);
            }
        }

        if(questionTypeIds.contains("3")){
            String askJoins = exam.getAskJoins();
            for (String askId : askJoins.split(",")) {
                Ask ask = askMapper.selectById(askId);
                asks.add(ask);
            }
        }


        if(questionTypeIds.contains("4")){
            String upperJoins = exam.getUpperJoins();
            Upper upper = upperMapper.selectById(upperJoins);
            uppers.add(upper);
        }

        map.put("singleList",singles);
        map.put("selectionList",selections);
        map.put("askList",asks);
        map.put("upperList",uppers);

        return new Result(ResultCode.SUCCESS,map);
    }

    public Result superviseExam(Map<String, Object> map) throws ParseException {
        String classesId = map.get("classesId").toString();
        String examType = map.get("examType").toString();
        List<String> date = (List<String>) map.get("date");
        Date startDate = new SimpleDateFormat("yyyy-MM-dd").parse(date.get(0));
        Date endDate = new SimpleDateFormat("yyyy-MM-dd").parse(date.get(1));


        //查询班级这个月所有的考试,获得examTime 用于table表格的表头
        QueryWrapper<Exam> examQueryWrapper = new QueryWrapper<>();
        examQueryWrapper.eq("classes_id",classesId);
        examQueryWrapper.between("exam_time",startDate,endDate);
        examQueryWrapper.eq("exam_type",examType);
        examQueryWrapper.orderByAsc("exam_time");
        List<Exam> exams = examMapper.selectList(examQueryWrapper);


        //处理表头数据
        List<String> headers = new ArrayList<>();
        if(exams != null && exams.size() > 0){
            for (Exam exam : exams) {
                Date examTime = exam.getExamTime();
                String month = String.format("%tm", examTime);
                String day = String.format("%td",examTime);
                String header = month + "月" + day + "日";
                headers.add(header);
            }
        }else{
            return new Result(ResultCode.CLASSES_NO_EXAMS);
        }

        //查询班级所有学生
        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.eq("classes_id",classesId);
        List<Student> students = studentManagerMapper.selectList(studentQueryWrapper);


        List<Map<String,Object>> studentList = new ArrayList<>();

        //获得单个学生 日期范围内的所有成绩
        if(students != null && students.size() > 0){
            for (Student student : students) {
                Map<String,Object> studentMap = new HashMap<>();
                studentMap.put("studentId",student.getId());

                User user = userRepository.findById(student.getId()).get();
                studentMap.put("nickName",user.getNickName());

                List<Integer> resultScores = new ArrayList<>();

                for (Exam exam : exams) {
                    studentMap.put("examId",exam.getId());

                    QueryWrapper<Score> scoreQueryWrapper = new QueryWrapper<>();
                    scoreQueryWrapper.eq("student_id",student.getId());
                    scoreQueryWrapper.eq("exam_id",exam.getId());
                    List<Score> scores = scoreMapper.selectList(scoreQueryWrapper);

                    if(scores != null && scores.size() > 0){
                        for (Score score : scores) {
                            studentMap.put("scoreId",score.getId());
                            if("0".equals(score.getStatus())){ //未参与考试
                                resultScores.add(-1);
                            }else{
                                resultScores.add(score.getScore());
                            }
                        }
                    }
                }

                //求平均分
                int size = resultScores.size();
                if(size == 0){
                    studentMap.put("avg",0D);
                }else{
                    int sum = 0;
                    for (Integer resultScore : resultScores) {
                        if(resultScore == -1){
                            continue;
                        }else{
                            sum += resultScore;
                        }
                    }
                    int avg = sum / size;
                    studentMap.put("avg",avg);
                }

                studentMap.put("scores",resultScores);
                studentList.add(studentMap);
            }
        }

        //添加头部和数据
        Map<String,Object> returnMap = new HashMap<>();

        returnMap.put("headers",headers);
        returnMap.put("vos",studentList);

        return new Result(ResultCode.SUCCESS,returnMap);
    }

}
